home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 16 / develop 16 code / CollaboDraw / myevents.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-24  |  12.1 KB  |  596 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------------------------
  2.  *
  3.  * Simple Sample PowerTalk Application Framework
  4.  *
  5.  * ©1991-1993 Apple Computer
  6.  *
  7.  -------------------------------------------------------------------------------------*/
  8. /*
  9.  * myevents.c -- main event loop and basic event handling
  10.  *
  11.  * change history:
  12.  *
  13.  * SJF        08/23/93        1.0f1        update to final headers, fix comments
  14.  * SJF        04/21/93        1.0b2        update to b2
  15.  * SJF        03/01/93        1.0b1        added digital signatures
  16.  * SJF        02/09/93        1.0b1        update to b1
  17.  * SJF        10/13/92        1.0d4        update to a11
  18.  * SJF        09/09/92        1.0d3        update to a9
  19.  * SJF        05/07/92        1.0d2        update to a6
  20.  * SJF        11/06/91        1.0d1        initial coding
  21.  *
  22.  */
  23.  
  24. #ifndef __TYPES__
  25. #include <Types.h>
  26. #endif
  27.  
  28. #ifndef __QUICKDRAW__
  29. #include <QuickDraw.h>
  30. #endif
  31.  
  32. #ifndef __MENUS__
  33. #include <Menus.h>
  34. #endif
  35.  
  36. #ifndef __EVENTS__
  37. #include <Events.h>
  38. #endif
  39.  
  40. #ifndef __APPLEEVENTS__
  41. #include <AppleEvents.h>
  42. #endif
  43.  
  44. #ifndef __DESK__
  45. #include <Desk.h>
  46. #endif
  47.  
  48. #ifndef __TOOLUTILS__
  49. #include <ToolUtils.h>
  50. #endif
  51.  
  52. #include "const.h"
  53. #include "mytypes.h"
  54. #include "mymenus.h"
  55. #include "globals.h"
  56. #include "utils.h"
  57. #include "mystandardmail.h"
  58. #include "windowstuff.h"
  59. #include "commands.h"
  60. #include "aevt.h"
  61. #include "windutils.h"
  62. #include "digisig.h"
  63.  
  64. #include "myevents.h"
  65.  
  66. /* main event loop */
  67.  
  68. void MainLoop(void)
  69. {
  70.     EventRecord ev;
  71.     Boolean gotEvent;
  72.     Point mousePt;
  73.     
  74.     gCursorRgn = NewRgn();
  75.     
  76.     // note: even this is an AOCE sample, I still support single-finder since the application
  77.     // runs without AOCE being present, just like a well-behaved app should
  78.     
  79.     while (!gDone) {
  80.         if (gHasWaitNextEvent)
  81.             gotEvent = WaitNextEvent(everyEvent,&ev,SleepTime(),gCursorRgn);
  82.         else {
  83.             gotEvent = GetNextEvent(everyEvent,&ev);
  84.             SystemTask();
  85.         }
  86.         
  87.         ProcessEvent(&ev);    // process the event we got
  88.         
  89.         if (gotEvent) {
  90.             GetMouse(&mousePt);
  91.             LocalToGlobal(&mousePt);
  92.             HandleFixCursor(mousePt,gCursorRgn);
  93.         }
  94.         
  95.         if (gMenusDirty) {
  96.             DrawMenuBar();
  97.             gMenusDirty = false;
  98.         }
  99.     }
  100.     
  101.     DisposeRgn(gCursorRgn);
  102. }
  103.  
  104.  
  105. /* calculate how long to "wait" */
  106.  
  107. long SleepTime(void)
  108. {
  109.     if (gInBackground)
  110.         return kSleepBackground;
  111.     else
  112.         return kSleepForeground;
  113. }
  114.  
  115.  
  116. /* set cursor shape depending on mouse location */
  117.  
  118. void HandleFixCursor(Point where,RgnHandle theRgn)
  119. {
  120.     WindowPtr window;
  121.     unsigned long crsrData[2];
  122.     
  123.     if (!gInBackground) {
  124.         window = MyFrontWindow();
  125.         
  126.         if (IsAppWindow(window)) {
  127.             crsrData[0] = *((unsigned long *) &where);
  128.             crsrData[1] = (unsigned long)theRgn;
  129.             SendWindowMessage(window,kFixCursorMessage,crsrData);
  130.         }
  131.         else {
  132.             // we don't want a stream of mouse moved events
  133.             SetRectRgn(theRgn,-32767,-32767,32767,32767);
  134.             SetCursor(&qd.arrow);
  135.         }
  136.     }
  137. }
  138.  
  139.  
  140. /* idle time processing */
  141.  
  142. void HandleIdle(WindowPtr window)
  143. {
  144.     if (IsAppWindow(window))
  145.         SendWindowMessage(window,kIdleMessage,nil);
  146. }
  147.  
  148.  
  149. /* process an event gotten by MainLoop() */
  150.  
  151. void ProcessEvent(EventRecord *ev)
  152. {
  153.     void *returnResult;
  154.     WindowPtr evWindow;
  155.     
  156.     if (ev->what==updateEvt)
  157.         evWindow = (WindowPtr)(ev->message);
  158.     else
  159.         evWindow = MyFrontWindow();
  160.             
  161.     returnResult = SendWindowMessage(evWindow,kEventMessage,ev);
  162.     if (returnResult!=nil)
  163.         return;
  164.  
  165.     switch (ev->what) {
  166.             case mouseDown:
  167.                 HandleMouseDowns(ev);
  168.                 break;
  169.             case keyDown:
  170.             case autoKey:
  171.                 HandleKeyDowns(ev);
  172.                 break;
  173.             case updateEvt:
  174.                 HandleUpdates((WindowPtr)ev->message);
  175.                 break;
  176.             case activateEvt:
  177.                 HandleActivates(ev);
  178.                 break;
  179.             case osEvt:
  180.                 HandleSREvt(ev->where,ev->message);
  181.                 break;
  182.             case kHighLevelEvent:
  183.                 DoHighLevelEvent(ev);
  184.                 break;
  185.             case nullEvent:
  186.                 HandleIdle(MyFrontWindow());
  187.                 break;
  188.     }
  189. }
  190.  
  191.  
  192. /* Handles suspend and resume events */
  193.  
  194. void HandleSREvt(Point where,long message)
  195. {
  196.     extern NMRec *gNotify;
  197.     extern Boolean gInBackground;
  198.     unsigned long whatMessage;
  199.     
  200.     whatMessage = message >> 24;
  201.     
  202.     if (whatMessage==suspendResumeMessage) {
  203.         if ((message & 1) != 0) {
  204.             gInBackground = false;
  205.             SetCursor(&qd.arrow);
  206.             if (MyFrontWindow()) {
  207.                 HiliteWindow(MyFrontWindow(),true);
  208.                 DoActivate(MyFrontWindow(),true);
  209.             }
  210.         }
  211.         else if (MyFrontWindow()) {
  212.             gInBackground = true;
  213.             HiliteWindow(MyFrontWindow(),false);
  214.             DoDeActivate(MyFrontWindow(),true);
  215.         }
  216.     }
  217.     else if ((whatMessage&mouseMovedMessage)==mouseMovedMessage)
  218.         HandleFixCursor(where,gCursorRgn);
  219. }
  220.  
  221.  
  222. /* Handles activate and deactivate events for a window */
  223.  
  224. void HandleActivates(EventRecord *ev)
  225. {
  226.     if ((ev->modifiers & activeFlag) != 0) {
  227.         DoActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
  228.     }
  229.     else {
  230.         DoDeActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
  231.     }
  232. }
  233.  
  234.  
  235. /* Handles activate events for a window */
  236.  
  237. void DoActivate(WindowPtr window,Boolean chFlag)
  238. {
  239.     SendWindowMessage(window,kActivateMessage,&chFlag);
  240. }
  241.  
  242.  
  243. /* Handles deactivate events for a window */
  244.  
  245. void DoDeActivate(WindowPtr window,Boolean chFlag)
  246. {
  247.     SendWindowMessage(window,kDeactivateMessage,&chFlag);
  248. }
  249.  
  250.  
  251. /* handles update events for a window */
  252.  
  253. void HandleUpdates(WindowPtr window)
  254. {
  255.     GrafPtr savePort;
  256.     
  257.     GetPort(&savePort);
  258.     SetPort(window);
  259.     BeginUpdate(window);
  260.     EraseRect(&window->portRect);
  261.     SendWindowMessage(window,kUpdateMessage,nil);
  262.     EndUpdate(window);
  263.     SetPort(savePort);
  264. }
  265.  
  266.  
  267. /* handles program keydowns */
  268.  
  269. void HandleKeyDowns(EventRecord *ev)
  270. {
  271.     short theChar;
  272.     WindowPtr window;
  273.     
  274.     theChar = ev->message & charCodeMask;
  275.     if ((ev->modifiers & cmdKey) != 0)
  276.         DoMenuCommand(MenuKey(theChar));
  277.     else if (IsAppWindow(window=MyFrontWindow()))
  278.         SendWindowMessage(window,kKeyMessage,&theChar);
  279. }
  280.  
  281.  
  282. /* handles mouse down events for a window */
  283.  
  284. void HandleMouseDowns(EventRecord *ev)
  285. {
  286.     WindowPtr window;
  287.     short part;
  288.     
  289.     part = FindWindow(ev->where,&window);
  290.     
  291.     switch (FindWindow(ev->where,&window)) {
  292.         case inMenuBar:
  293.             DoMenuCommand(MenuSelect(ev->where));
  294.             break;
  295.         case inSysWindow:
  296.             SystemClick(ev,window);
  297.             break;
  298.         case inDrag:
  299.             DoDrag(window,ev->where);
  300.             break;
  301.         case inGrow:
  302.             DoGrow(window,ev->where);
  303.             break;
  304.         case inGoAway:
  305.             if (TrackGoAway(window,ev->where)) {
  306.                 CommCloseWindow(window);
  307.             }
  308.             break;
  309.         case inZoomIn:
  310.         case inZoomOut:
  311.             if (TrackBox(window,ev->where,FindWindow(ev->where,&window)))
  312.                 DoZoom(window,FindWindow(ev->where,&window));
  313.             break;
  314.         case inContent:
  315.             DoContentClick(window,ev);
  316.             break;
  317.     }
  318. }
  319.  
  320.  
  321. /* handles window dragging */
  322.  
  323. void DoDrag(WindowPtr window,Point globMouse)
  324. {
  325.     Rect dragRect = kWindowDragLimits;
  326.         
  327.     DragWindow(window,globMouse,&dragRect);
  328.     SetPort(window);
  329. }
  330.  
  331.  
  332. /* handles window growing */
  333.  
  334. void DoGrow(WindowPtr window,Point globMouse)
  335. {
  336.     long newSize;
  337.     Rect windLimits;
  338.     Rect oldSize;
  339.     GrafPtr tempPort;
  340.     WInfoHndl infoHndl;
  341.     
  342.     if (!IsAppWindow(window))
  343.         return;
  344.         
  345.     infoHndl = GetWindowInfo(window);
  346.     windLimits = (**((**infoHndl).printRecord)).prInfo.rPage;
  347.     windLimits.right += windLimits.left+kScrollBarWidth+1+(**infoHndl).leftIndent;
  348.     windLimits.bottom += windLimits.top+kScrollBarWidth+1+(**infoHndl).topIndent;
  349.     windLimits.left = 100;
  350.     windLimits.top = 100;
  351.     
  352.     oldSize = window->portRect;
  353.     if ((newSize = GrowWindow(window,globMouse,&windLimits)) != 0) {
  354.         GetPort(&tempPort);
  355.         SetPort(window);
  356.         SizeWindow(window,LoWord(newSize),HiWord(newSize),true);
  357.         InvalRect(&window->portRect);
  358.         SendWindowMessage(window,kResizeMessage,&oldSize);
  359.         SetPort(tempPort);
  360.     }
  361. }
  362.  
  363.  
  364. /* handles window zooms */
  365.  
  366. // note: this stuff is a little off: the stdState can't grow any bigger when it needs to
  367. // (when the user changes the page setup for example).  I didn't spend the time to put in
  368. // a "real" zoom feature, because it doesn't show off any of the PowerTalk features
  369. //
  370. void DoZoom(WindowPtr window,short zoomDir)
  371. {
  372.     GrafPtr savePort;
  373.     WInfoPtr infoPtr;
  374.     char hState;
  375.     Rect oldSize;
  376.     short newWidth,newHeight;
  377.     WStateData **stateHndl;
  378.     Rect userState,stdState;
  379.     
  380.     GetPort(&savePort);
  381.     infoPtr = BeginWindowAccess(window,&hState);
  382.     SetPort(window);
  383.  
  384.     oldSize = window->portRect;
  385.     stateHndl = (WStateData **) ((WindowPeek)window)->dataHandle;        
  386.     userState = (**stateHndl).userState;
  387.     stdState = (**stateHndl).stdState;
  388.     
  389.     ClipPageSize(&stdState,infoPtr,&newWidth,&newHeight);
  390.     stdState.right = stdState.left+newWidth;
  391.     stdState.bottom = stdState.top+newHeight;
  392.     (**stateHndl).stdState = stdState;
  393.     
  394.     ZoomWindow(window,zoomDir,true);
  395.     EraseRect(&window->portRect);
  396.         
  397.     InvalRect(&window->portRect);
  398.     SendWindowMessage(window,kResizeMessage,&oldSize);
  399.  
  400.     EndWindowAccess(window,hState);
  401.     SetPort(savePort);    
  402. }
  403.  
  404.  
  405. /* handles a click in a window content region */
  406.  
  407. void DoContentClick(WindowPtr window,EventRecord *ev)
  408. {
  409.     short part;
  410.     Point mousePos;
  411.     ControlHandle hitControl;
  412.     ControlHitMessage ctrlMessage;
  413.     
  414.     if (window != MyFrontWindow()) {
  415.         SelectWindow(window);
  416.         return;
  417.     }
  418.     
  419.     mousePos = ev->where;
  420.     SetPort(window);
  421.     GlobalToLocal(&mousePos);
  422.     part = FindControl(mousePos,window,&hitControl);
  423.     
  424.     if (hitControl) {
  425.         ctrlMessage.part = part;
  426.         ctrlMessage.control = hitControl;
  427.         ctrlMessage.ev = ev;
  428.         SendWindowMessage(window,kHitControlMessage,&ctrlMessage);
  429.     }
  430.     else
  431.         SendWindowMessage(window,kClickMessage,ev);        
  432. }
  433.  
  434.  
  435. /* handles menu commands */
  436.  
  437. void DoMenuCommand(long mResult)
  438. {
  439.     short selItem,selMenu,temp;
  440.     Str255 name;
  441.     GrafPtr tempPort;
  442.     MenuHandle theMenu;
  443.     
  444.     selItem = LoWord(mResult);
  445.     selMenu = HiWord(mResult);
  446.     switch (selMenu) {
  447.         case kAppleMenu:
  448.             if (selItem>2) {
  449.                 GetPort(&tempPort);
  450.                 SetCursor(&qd.arrow);
  451.                 theMenu = GetMHandle(kAppleMenu);
  452.                 GetItem(theMenu,selItem,name);
  453.                 temp = OpenDeskAcc(name);
  454.                 SetPort(tempPort);
  455.             }
  456.             else CommAbout();
  457.             break;
  458.         case kFileMenu:
  459.             switch (selItem) {
  460.                 case kNewItem:
  461.                     CommNew();
  462.                     break;
  463.                 case kOpenItem:
  464.                     CommOpen();
  465.                     break;
  466.                 case kCloseItem:
  467.                     CommCloseWindow(MyFrontWindow());
  468.                     break;
  469.                 case kSaveItem:
  470.                     CommSaveFile(MyFrontWindow());
  471.                     break;
  472.                 case kSaveAsItem:
  473.                     CommSaveAsFile(MyFrontWindow());
  474.                     break;
  475.                 case kPageSetupItem:
  476.                     CommPageSetup(MyFrontWindow());
  477.                     break;
  478.                 case kPrintItem:
  479.                     CommPrint(MyFrontWindow());
  480.                     break;
  481.                 case kQuitItem:
  482.                     gDone = true;
  483.                     break;
  484.             }
  485.             break;
  486.         case kEditMenu:
  487.             switch (selItem) {
  488.                 case kPrefsItem:
  489.                     CommEditPreferences();
  490.                     break;
  491.                 default:
  492.                     if (selItem>kClearItem)
  493.                         CommEdit(MyFrontWindow(),selItem);
  494.                     else if (!(SystemEdit(selItem-1)))
  495.                         CommEdit(MyFrontWindow(),selItem);
  496.                     break;
  497.             }
  498.             break;
  499.         case kShapesMenu:
  500.             switch (selItem) {
  501.                 case kGroupItem:
  502.                     SendWindowMessage(MyFrontWindow(),kGroupMessage,nil);
  503.                     break;
  504.                 case kUngroupItem:
  505.                     SendWindowMessage(MyFrontWindow(),kUnGroupMessage,nil);
  506.                     break;
  507.                 default:
  508.                     theMenu = GetMHandle(kShapesMenu);
  509.                     CheckItem(theMenu,gCurrentShape,false);
  510.                     CheckItem(theMenu,selItem,true);
  511.                     gCurrentShape = selItem;
  512.                     break;
  513.             }
  514.             break;
  515.         case kMailMenu:
  516.             switch (selItem) {
  517.                 case kSendItem:
  518.                     CommSendLetter(MyFrontWindow());
  519.                     break;
  520.                 case kAddRemMailItem:
  521.                     CommAddRemoveMailer(MyFrontWindow());
  522.                     break;
  523.                 case kReplyItem:
  524.                     CommReply(MyFrontWindow(),false);
  525.                     break;
  526.                 case kReplyToAllItem:
  527.                     CommReply(MyFrontWindow(),true);
  528.                     break;
  529.                 case kForwardItem:
  530.                     CommForward(MyFrontWindow());
  531.                     break;
  532.                 case kOpenNextItem:
  533.                     CommAdjacentLetter();
  534.                     break;
  535.                 case kTagLetterItem:
  536.                     CommTagLetter();
  537.                     break;
  538.             }
  539.             break;
  540.         case kSignMenu:
  541.             switch (selItem) {
  542.                 case kSignItem:
  543.                     CommSign(MyFrontWindow());
  544.                     break;
  545.                 case kVerifyItem:
  546.                     CommVerify(MyFrontWindow());
  547.                     break;
  548.                 case kShowSignItem:
  549.                     CommShowSigners(MyFrontWindow());
  550.                     break;
  551.             }
  552.             break;
  553.      }
  554.     HiliteMenu(0);
  555. }
  556.  
  557.  
  558. /* handles odoc appleevent */
  559.  
  560. OSErr HandleOpenDoc(Boolean diskForm, FSSpec *fSpec, LetterSpec *lSpec)
  561. {
  562.     WindowPtr window;
  563.     
  564.     return LoOpen(diskForm, fSpec, lSpec,true,&window);
  565. }
  566.  
  567.  
  568. /* handles pdoc appleevent */
  569.  
  570. OSErr HandlePrintDoc(Boolean diskForm, FSSpec *fSpec, LetterSpec *lSpec)
  571. {
  572.     OSErr err;
  573.     WindowPtr window;
  574.     
  575.     err = LoOpen(diskForm,fSpec,lSpec,false,&window);
  576.     if (err==noErr && window) {
  577.         SendWindowMessage(window,kPrintMessage,nil);
  578.         CommCloseWindow(window);
  579.     }
  580.     return noErr;
  581. }
  582.  
  583.  
  584. /* called when the program is about to exit- closes all of our open windows */
  585.  
  586. Boolean ExitProgram(void)
  587. {
  588.     WindowPtr window;
  589.     
  590.     while ((window=MyFrontWindow()) && gDone)
  591.         CommCloseWindow(window);
  592.     
  593.     return gDone;
  594. }
  595.  
  596.